package com.example.skincoredemo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.skincoredemo.utils.GloablConfig;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;

// 用于换肤的自定义的创建View的工厂
public class SkinLayoutFactory implements LayoutInflater.Factory2 , Observer {

    private static final String[] mClassPrefixList = {  // 系统自带View包名路径集合
            "android.view.",
            "android.widget.",
            "android.webkit."
    };

    private static final Class[] mConstructorSignature = new Class[]{Context.class, AttributeSet.class};

    private static final HashMap<String, Constructor<? extends View>> mConstructor = new HashMap<>();

    private SkinAttribute skinAttribute;

    public SkinLayoutFactory() {
        skinAttribute = new SkinAttribute();
    }

    @Nullable
    @Override
    public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attributeSet) {

        // 创建系统自带View
        View view = createViewFromTag(name, context, attributeSet);

        // 为空则为是自定义View
        if (null == view) {
            view = createView(name, context, attributeSet); // 单独创建
        }

        // 筛选符合属性View (核心步骤之一：采集需要换肤的控件)
        skinAttribute.load(view, attributeSet);

        return view;
    }

    private View createViewFromTag(String name, Context context, AttributeSet attributeSet) {
        //判断是否是自定义控件
        if (-1 != name.indexOf(".")) {
            return null;
        }
        View view = null;
        for (int i = 0; i < mClassPrefixList.length; i++) {
            view = createView(mClassPrefixList[i] + name, context, attributeSet);
            if (view != null) {
                break;
            }
        }
        return view;
    }

    private View createView(String name, Context context, AttributeSet attributeSet) {
        Constructor<? extends View> constructor = mConstructor.get(name);
        if (constructor == null) {
            try {
                // 通过拼接后的全类名拿到Class
                Class<? extends View> aClass = context.getClassLoader().loadClass(name).asSubclass(View.class);
                // 再获取构造方法
                constructor = aClass.getConstructor(mConstructorSignature);
                // 缓存构造方法，后续使用就不需要重复创建了，节省性能
                mConstructor.put(name, constructor);
            } catch (Exception e) {
                Log.w(GloablConfig.LOG_TAG, e.getLocalizedMessage());
            }
        }
        if (constructor != null) {
            try {
                return constructor.newInstance(context, attributeSet);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull String s, @NonNull Context context, @NonNull AttributeSet attributeSet) {
        return null;
    }

    @Override
    public void update(Observable observable, Object o) {
        // 更换皮肤
        skinAttribute.applySkin();
    }
}
